package com.song.tools.songtest.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckOr;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.song.tools.core.beans.UserInfo;
import com.song.tools.core.beans.response.ResultVo;
import com.song.tools.core.util.UserUtil;
import com.song.tools.log.operatelog.annotation.OLog;
import com.song.tools.log.operatelog.core.LogRecordContext;
import com.song.tools.log.operatelog.enums.ActionTypeEnum;
import com.song.tools.log.operatelog.enums.ModuleEnum;
import com.song.tools.log.systemlog.annotation.SysLog;
import com.song.tools.mvc.controller.SuperCrudController;
import com.song.tools.mvc.request.BatchIdRequest;
import com.song.tools.mvc.request.IdRequest;
import com.song.tools.mvc.request.PageRequest;
import com.song.tools.mvc.response.PageResponse;
import com.song.tools.songtest.beans.request.SysUserLoginRequest;
import com.song.tools.songtest.beans.request.SysUserQueryRequest;
import com.song.tools.songtest.beans.request.SysUserSaveRequest;
import com.song.tools.songtest.beans.request.SysUserUpdateRequest;
import com.song.tools.songtest.beans.response.*;
import com.song.tools.songtest.beans.vo.UserVO;
import com.song.tools.songtest.config.WithoutLogin;
import com.song.tools.songtest.service.SysUserService;
import com.song.tools.songtest.trigger.SysUserTriggerManager;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author song tools
 * @since 2024-07-12
 */
@Tag(name = "用户表前端控制器")
@RestController
@RequestMapping("/sysUser")
public class SysUserController extends SuperCrudController<SysUserService, SysUserQueryRequest, SysUserQueryResponse, SysUserSaveRequest, SysUserSaveResponse, SysUserUpdateRequest, SysUserUpdateResponse, Long, SysUserDeleteResponse> {

    /**
     * 分页查询
     *
     * @param request 请求
     * @return 分页响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager"), @SaCheckRole("user")}
    )
    @SysLog("分页查询")
    @Override
    public ResultVo<PageResponse<SysUserQueryResponse>> listPages(PageRequest<SysUserQueryRequest> request) {
        return super.listPages(request);
    }

    /**
     * 查询信息（不分页）
     *
     * @param sysUserQueryRequest 请求
     * @return PageResponse 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager"), @SaCheckRole("user")}
    )
    @Override
    @SysLog("查询信息（不分页）")
    public ResultVo<List<SysUserQueryResponse>> list(SysUserQueryRequest sysUserQueryRequest) {
        return super.list(sysUserQueryRequest);
    }

    /**
     * 查询详细信息
     *
     * @param request 请求
     * @return 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager"), @SaCheckRole("user")}
    )
    @Override
    @SysLog("查询详细信息")
    public ResultVo<SysUserQueryResponse> getDetail(IdRequest<Long> request) {
        return super.getDetail(request);
    }

    /**
     * 新增
     *
     * @param sysUserSaveRequest 请求
     * @return 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager")}
    )
    @Override
    @SysLog("新增")
    public ResultVo<SysUserSaveResponse> save(SysUserSaveRequest sysUserSaveRequest) {
        return super.save(sysUserSaveRequest);
    }

    /**
     * 修改
     *
     * @param sysUserUpdateRequest 请求
     * @return 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager")}
    )
    @Override
    @SysLog("修改")
    public ResultVo<SysUserUpdateResponse> update(SysUserUpdateRequest sysUserUpdateRequest) {
        return super.update(sysUserUpdateRequest);
    }

    /**
     * 删除
     *
     * @param request 请求
     * @return 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager")}
    )
    @Override
    @SysLog("删除")
    public ResultVo<SysUserDeleteResponse> delete(BatchIdRequest<Long> request) {
        return super.delete(request);
    }

    /**
     * 用户登录
     *
     * @param request 请求体
     * @return 登录响应体
     */
    @PostMapping("/login")
    @SysLog("用户登录")
    @Operation(summary = "用户登录")
    @WithoutLogin
    @SaIgnore
    public ResultVo<SysUserLoginResponse> login(@RequestBody SysUserLoginRequest request) {
        return ResultVo.success(SysUserTriggerManager.login(request));
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 响应
     */
    @SaCheckOr(
            role = {@SaCheckRole("manager"), @SaCheckRole("user")}
    )
    @SysLog("获取当前登录用户信息")
    @SaCheckLogin
    @PostMapping("/getUser")
    @OLog(template = "用户{loginAccount}获取当前登录信息", module = ModuleEnum.USER, actionType = ActionTypeEnum.QUERY, actionIdEl = "{userId}")
    @Operation(summary = "获取当前登录用户信息")
    public ResultVo<UserVO> getUser() {
        UserInfo userInfo = UserUtil.get();
        LogRecordContext.put("userId", String.valueOf(userInfo.id()));
        return ResultVo.success((UserVO) userInfo);
    }

    /**
     * 退出登录
     *
     * @return 响应
     */
    @Operation(summary = "退出登录")
    @SaCheckLogin
    @SysLog("退出登录")
    @OLog(template = "用户{loginAccount}退出登录，注销token: {token}", module = ModuleEnum.USER, actionType = ActionTypeEnum.LOGOUT, actionIdEl = "{userId}")
    @PostMapping("/logout")
    public ResultVo<Boolean> logout() {
        UserInfo userInfo = UserUtil.get();
        StpUtil.logoutByTokenValue(userInfo.token());
        LogRecordContext.put("userId", String.valueOf(userInfo.id()));
        LogRecordContext.put("loginAccount", userInfo.loginAccount());
        LogRecordContext.put("token", userInfo.token());
        return ResultVo.success(true);
    }
}
